package org.jprogger.myworld.api.response;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;


/**
 * 
 * @author jprogger
 *
 */
class ApiResponseErrorValidator {

	private int code;
	private String message;
	private boolean hasError;
	
	public boolean hasError() {
		return hasError;
	}
	
	public int getErrorCode() {
		return code;
	}
	
	public String getErrorMessage() {
		return message;
	}
	
	private void validateJson(String response){
		
		JsonParser parser = new JsonParser();
		JsonElement element = parser.parse(response);
		
		if (element.isJsonObject()) 
		{
			JsonObject object = element.getAsJsonObject();
			if (object.has("error")) 
			{	
				hasError = true;
				for(Map.Entry<String, JsonElement> entry: object.entrySet()) 
				{
					JsonObject obj = null;
					if (entry.getValue().isJsonObject()) 
					{
						obj = entry.getValue().getAsJsonObject();					
						if (obj.has("error_msg"))
						{
							JsonElement errorMsg = obj.get("error_msg");
							message = errorMsg.getAsString();
						}
						if (obj.has("error_code"))
						{
							JsonElement errorCode = obj.get("error_code");
							code = errorCode.getAsInt();
						}
					}
				}
			}
		}
	}
	
	private void validateXml(String response) throws ParseResponseException {
		
		DocumentBuilderFactory factory = null;
		DocumentBuilder builder = null;
		Document document = null;
		
		try 
		{
			factory = DocumentBuilderFactory.newInstance();
			builder = factory.newDocumentBuilder();
			InputStream is = new ByteArrayInputStream(response.getBytes());
			document = builder.parse(is);
			NodeList list = document.getElementsByTagName("error");
			if (list != null) 
			{
				Node errorNode = list.item(0);
				if (errorNode != null && errorNode.hasChildNodes())
				{
					hasError = true;
					NodeList errorContentList = errorNode.getChildNodes();
					for (int i = 0; i < errorContentList.getLength(); i++) {
						Node node = errorContentList.item(i);
						if (node.getNodeName().equals("error_code")) 
						{
							code = Integer.parseInt(node.getFirstChild().getNodeValue());
						}
						else if (node.getNodeName().equals("error_msg"))
						{
							message = node.getFirstChild().getNodeValue();
						}
					}
				}
			}
		}
		catch (ParserConfigurationException pce) 
		{
			throw new ParseResponseException(pce);
		}
		catch (SAXException sxe) 
		{
			throw new ParseResponseException(sxe);
		}
		catch (IOException ioe) {
			throw new ParseResponseException(ioe);
		}

	}
			
	public void validate(String responseString, String format) throws ParseResponseException {
		
		if (format != null && format.equalsIgnoreCase("xml"))
		{
			validateXml(responseString);
		}
		else
		{
			validateJson(responseString);
		}

	}
}
